package typejump.gui;
import javax.swing.JButton;
import javax.swing.JPanel;

import typejump.TypeJump;
import typejump.engine.Drawable;
import typejump.engine.GameEngine;
import typejump.objects.GameObject;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.LinkedList;

@SuppressWarnings("serial")
/**
 * This is a GUI component which paints the game screen.
 * @author g
 *
 */
public class Canvas extends JButton {
	
	private BufferedImage backbuffer;

	private LinkedList<UIWidget> widgets;
	private final Object widglock = new Object();
	private volatile boolean running = false;
	
	public Canvas() {
		setFocusable(true);
		setPreferredSize(new Dimension(TypeJump.SCREEN_WIDTH, TypeJump.SCREEN_HEIGHT));
		genBackBuffer();
		
		widgets = new LinkedList<UIWidget>();
	}
	
	public synchronized void start() {
		if (running) return;
		running = true;
		new Thread() {
			@Override
			public void run() {
				while (true) {
					repaint();
						
					try {
						Thread.sleep(10);
					} catch (Exception e) {
						
					}
				}
			}
		}.start();
	}
	
	
	
	private void genBackBuffer() {
		backbuffer = new BufferedImage(Math.max(1, getWidth()), Math.max(1, getHeight()), BufferedImage.TYPE_INT_RGB);
	}
	
	/**
	 * Adds the UIWidget to the list of widgets to be painted over the screen
	 * @param widget
	 */
	public void addWidget(UIWidget widget) {
		synchronized (widglock) {
			if (!widgets.contains(widget)) {
				widgets.add(widget);
			}
		}
	}
	
	/**
	 * Removes the UIWidget from the list of widgets to be painted over the screen
	 * @param widget
	 * @return
	 */
	public boolean removeWidget(UIWidget widget) {
		synchronized (widglock) {
			return widgets.remove(widget);
		}
	}
	/**
	 * Gets the position of the mouse pointer in the game world
	 * @return
	 */
	public double getPointerX() {
		try { return getMousePosition().x - getTranslateX(); }
		catch (Exception e) {return -1;}
	}
	
	/**
	 * Gets the position of the mouse pointer in the game world
	 * @return
	 */
	public double getPointerY() {
		try { return getMousePosition().y - getTranslateY(); }
		catch (Exception e) {return -1;}
	}
	
	private double getTranslateX() {
		return GameEngine.getTranslateX() + (getWidth() * 0.25);
	}
	
	private double getTranslateY() {
		return GameEngine.getTranslateY() + getHeight() - 150;
	}
	
	@Override
	public void paint(Graphics gg) {
		if (backbuffer.getWidth() != getWidth() || backbuffer.getHeight() != getHeight()) {
			genBackBuffer();
		}
		
		Graphics2D g = backbuffer.createGraphics();
		
		g.setColor(GameEngine.getBackgroundColor());
		g.fillRect(-1, -1, getWidth()+2, getHeight()+2);
			
		synchronized (GameEngine.getObjectLock("Paint stuff")) {
			Iterable<GameObject> objects = GameEngine.getObjects();
			double mtx = getTranslateX();
			double mty = getTranslateY();
			
			g.translate(mtx, mty);
			
			g.setColor(Color.RED);
			
			int x = 0;
			int y = 0;

			for (Drawable d : objects) {
				if (d.paintEnabled()) {
					x = d.getTranslateX();
					y = d.getTranslateY();
					g.translate(x, y);
					d.paint(g);
					g.translate(-x, -y);
				}
			}
			
			GameEngine.getSelection().paint(g);
			
			g.translate(-mtx, -mty);
		}
		
		synchronized (widglock) {
		for (UIWidget w : widgets) {
			w.setAvailableSpace(getWidth(), getHeight());
			w.paint(g);
		}
		}
		
		gg.drawImage(backbuffer, 0, 0, null);
	}
}
